#include <stdio.h>
#include "mpx_supt.h"
#include "mrj_supt.h"

pcb* findPCB(char*);
pcb* searchPCBbyName(char*);
void insertPCB(char*, pcb*);
void removePCB(char*);
void pcb_setp(char*);
void suspend_pcb(char*);
void resume_pcb(char*);
void pcb_info(char*);
void pcb_block(char*);
void pcb_unblock(char*);
void new_pcb(char*);
void delete_pcb(char*);
char* remove_ws(char*);

pcb* findPCB(char* name)
{
	pcb *ret = searchPCBbyName(name);
	return ret;
}

void insertPCB(char* queue, pcb* newPCB)
{
	if((queue[0] == 'b') || (queue[0] == 'B'))
	{
		enqueueBlocked(newPCB);
	}
	
	else if((queue[0] == 'r') || (queue[0] == 'R'))
	{
		enqueueReady(newPCB);
	}
	
	else
	{
		printf("Please enter either 'B' or 'R'\n");
	}
}

void removePCB(char* queue)
{
	
	if((queue[0] == 'r') || (queue[0] == 'R'))
	{
		dequeueReady();
	}
	
	else if((queue[0] == 'b') || (queue[0] == 'B'))
	{
		dequeueBlocked();
	}
}

void suspend_pcb(char* pName){
	pcb* pcbid = searchPCBbyName(pName);
	if(pcbid){
		pcbid->susp=PCB_FLAG_SUSP;
		printf("%s is now suspended.\n", pName);
	}
	else{
		printf("Error: Could not suspend %s. Process DNE.\n", pName);
	}
}

void resume_pcb(char* pName){
	pcb* pcbid = searchPCBbyName(pName);
	if(pcbid){
		pcbid->susp=PCB_FLAG_FREE;
		printf("%s has resumed.\n", pName);
	}
	else{
		printf("Error: Could not resume %s. Process DNE.\n", pName);
	}
}

void pcb_info(char* pName){
	pcb* pcbid = searchPCBbyName(pName);
	if(pcbid){
		printf("name: %s\tstate: %d\tpriority: %d\tclass: %dsize: %d\n", pcbid->name, pcbid->state, pcbid->priority, pcbid->Pclass, pcbid->memSize);
	}else{
		printf("%s does not exist.\n", pName);
	}
}

//pcb -blok pName
void block_pcb(char* pName){
	pcb* pcbid = searchPCBbyName(pName);
	if(pcbid){
		pcbid->state = PCB_STATE_BLK;
		dequeueReadyMiddle(pcbid);
		enqueueBlocked(pcbid);
	}else{
		printf("Error: Could not block %s. Process DNE.\n", pName);
	}
}

void unblock_pcb(char* pName){
	pcb* pcbid = searchPCBbyName(pName);
	if(pcbid){
		pcbid->state = PCB_STATE_RDY;
		dequeueBlocked();
		enqueueReady(pcbid);
	}else{
		printf("Error: Could not unblock %s. Process DNE.\n", pName);
	}
}

//pcb -del pName
void delete_pcb(char* pName){
	pcb* pcbid = searchPCBbyName(pName);
	//removePCB('r');
	if(pcbid){
		if(!free_pcb(pcbid)){
			printf("pcb: %s successfully killed.\n", pName);
		}else{
			printf("unable to free pcb: %s\n", pName);
		}
	}else{
		printf("Error: Could not kill %s. Process DNE.\n", pName);
	}
	
}

//pcb -new pName (int)priority (int)class
void new_pcb(char* args){
	int aLen = strlen(args);
	char pName[20]={'\0'};
	int priority=0;
	int pClass=0;
	int a=0;
	int nFlag=1;
	int pindex=0;
	int cindex=0;
	pcb* fresh;
	//copy the process name from cmd argument to new string
	while(!((args[a]==' ')||(args[a]=='\t')||(args[a]=='\n'))){
		pName[a] = args[a];
		a++;
	}
	pName[a]='\0';
	//ignore ws
	
	while((args[a]==' ')||(args[a]=='\t')||(args[a]=='\n')){
		a++;
	}
	if(args[a]=='-'){
		nFlag=-1;
		a++;
	}
	//turn 2nd arg into int

	while(!((args[a]==' ')||(args[a]=='\t')||(args[a]=='\n')) && a<aLen){
		priority = (int)(args[a])-48 + priority*10;
		pindex++;
		a++;
	}
	//ignore ws
	while((args[a]==' ')||(args[a]=='\t')||(args[a]=='\n')){
		a++;
	}
	//turn 3rd arg into int

	while(!((args[a]==' ')||(args[a]=='\t')||(args[a]=='\n')) && a < aLen){
		pClass += ((int)(args[a]))-48 ;
		cindex++;
		a++;
	}
	priority *= nFlag;
	fresh = setPCB(pName, priority, pClass);
	if(fresh){
		enqueueReady(fresh);
	}
	else{
		printf("Unable to create new pcb.\n");
	}
}

	